from PIL import Image
import io
from .format_config import SUPPORTED_FORMATS, FORMATS_BY_CATEGORY, READ_WRITE_CAPABILITY

class ImageConverter:
    """图片格式转换核心类"""
    
    def __init__(self):
        """初始化转换器"""
        pass
    
    def convert(self, source_path, target_path, target_format, quality=None, max_size_mb=None):
        """
        执行图片格式转换
        :param source_path: 源图片路径
        :param target_path: 目标保存路径
        :param target_format: 目标格式 (小写)
        :param quality: 质量参数(1-100)
        :param max_size_mb: 最大文件大小(MB)
        :return: 无
        """
        try:
            # 验证目标格式是否支持
            if target_format.lower() not in SUPPORTED_FORMATS:
                raise ValueError(f"不支持的格式: {target_format}")
            
            # 打开源图片
            with Image.open(source_path) as img:
                # 设置保存参数
                save_kwargs = {
                    'format': SUPPORTED_FORMATS[target_format.lower()],
                    'quality': quality if quality else 95
                }
                
                # 处理WEBP格式的特殊参数
                if target_format.lower() == 'webp':
                    save_kwargs['method'] = 6  # 默认使用最高质量压缩方法
                
                # 如果需要限制文件大小
                if max_size_mb:
                    return self._convert_with_size_limit(
                        img, target_path, max_size_mb, **save_kwargs
                    )
                
                # 普通转换
                img.save(target_path, **save_kwargs)
                
        except Exception as e:
            raise Exception(f"转换失败: {str(e)}")
    
    def _convert_with_size_limit(self, img, target_path, max_size_mb, **save_kwargs):
        """带文件大小限制的转换"""
        max_bytes = max_size_mb * 1024 * 1024
        quality = save_kwargs.get('quality', 95)
        
        # 逐步降低质量直到满足大小要求
        while quality >= 10:
            buffer = io.BytesIO()
            img.save(buffer, **save_kwargs)
            
            if buffer.tell() <= max_bytes:
                with open(target_path, 'wb') as f:
                    f.write(buffer.getvalue())
                return
            
            quality -= 5
            save_kwargs['quality'] = quality
        
        raise ValueError(f"无法压缩到{max_size_mb}MB以内")

    @staticmethod
    def get_supported_formats():
        """获取支持的格式列表"""
        from .format_config import get_all_formats
        return get_all_formats()
    
    @staticmethod
    def get_categories():
        """获取格式分类列表"""
        from .format_config import get_format_categories
        return get_format_categories()
    
    @staticmethod
    def get_formats_by_category(category):
        """获取指定分类的格式列表
        :param category: 分类名称
        :return: 格式字典 {扩展名: 描述}
        """
        from .format_config import get_formats_by_category
        return get_formats_by_category(category)